Compare commits

..
128 Commits
Author SHA1 Message Date
github-actions[bot]andCrowdin Bot a43538c919 [skip ci] chore(i18n): sync translations from crowdin (#2975)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-07 16:52:18 +02:00
Amruth Pillai faba604813 ci: do not run lingui:extract on autofix 2026-05-07 16:51:59 +02:00
github-actions[bot]andCrowdin Bot f8b3437e33 [skip ci] chore(i18n): sync translations from crowdin (#2974)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-07 16:50:29 +02:00
Amruth Pillai 4ac16df3d6 Merge branch 'main' of github.com:amruthpillai/reactive-resume 2026-05-07 16:49:48 +02:00
Amruth Pillai 4ae3e1a230 fix: update resume ID type from uuid to text and use generateId for ID generation 2026-05-07 16:49:44 +02:00
autofix-ci[bot] dcccbcfa9e [autofix.ci] apply automated fixes 2026-05-07 14:49:24 +00:00
Amruth Pillai 92a3916e76 fix: convert postgres uuid to text columns, to capture old cuid resume IDs 2026-05-07 16:48:25 +02:00
github-actions[bot]andCrowdin Bot 6321e99b9e [skip ci] chore(i18n): sync translations from crowdin (#2973)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-07 16:38:34 +02:00
github-actions[bot]andCrowdin Bot 94c953005e [skip ci] chore(i18n): sync translations from crowdin (#2972)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-07 16:31:49 +02:00
Amruth Pillai cf957692fc chore: update phosphor-icons-react-pdf to version 0.1.3 in package.json and pnpm-lock.yaml 2026-05-07 16:31:26 +02:00
Amruth Pillai 64492ce2f1 Merge branch 'main' of github.com:amruthpillai/reactive-resume 2026-05-07 15:19:19 +02:00
Amruth Pillai 4165c10a71 fix: readme banner image url 2026-05-07 15:19:13 +02:00
autofix-ci[bot] ef6961c9eb [autofix.ci] apply automated fixes 2026-05-07 13:18:55 +00:00
Amruth Pillai 13787db34a Merge branch 'main' of github.com:amruthpillai/reactive-resume 2026-05-07 15:16:34 +02:00
github-actions[bot]andCrowdin Bot f64daeb89e [skip ci] chore(i18n): sync translations from crowdin (#2971)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-05-07 15:15:23 +02:00
Amruth Pillai 6e447d1bcc Merge branch 'main' of github.com:amruthpillai/reactive-resume 2026-05-07 15:14:21 +02:00
Amruth Pillai 148d564fe8 fix: readme banner image url 2026-05-07 15:14:20 +02:00
Amruth Pillai 50ba37a27f v5.1.0 (#2970)
* chore(release): v5.1.0

* feat: implement resume thumbnails

* fix: remove unused mcp tools

* docs: fix formatting of docs
2026-05-07 15:12:33 +02:00
Joshua Fife 51c366310e Fixed docker compose for linux self hosted deployments (#2952) 2026-05-02 23:57:27 +02:00
Amruth Pillai 4e58ea6c8a chore: remove .devcontainer 2026-04-30 02:07:58 +02:00
Amruth Pillai fd892b0e14 fix: make the dash plugin optional
- fixes #2947
2026-04-29 23:30:07 +02:00
Amruth Pillai dc4830d41b chore: remove getSubsequentPageTopMarginStyle 2026-04-29 21:42:20 +02:00
Amruth Pillai 480e9a2612 fix: switch back to csp-report-only 2026-04-29 21:40:57 +02:00
Amruth Pillai 4cf5cdd181 fix: remove timeout to check data-wf-loaded 2026-04-29 21:38:40 +02:00
Amruth Pillai b9894c687c fix: handle /assets/ requests before it reaches orpc 2026-04-29 20:40:28 +02:00
autofix-ci[bot] 9048702cb8 [autofix.ci] apply automated fixes 2026-04-29 18:17:46 +00:00
Kuchizu dd94d070af fix: make AI resume analysis schema provider-compatible (#2939) 2026-04-29 20:16:29 +02:00
Amruth Pillai e035088269 fix: add-to-cache-list-conflicting-entries 2026-04-29 20:15:15 +02:00
Amruth Pillai 1fbe89bc01 update ipAddressHeaders 2026-04-29 19:55:31 +02:00
Amruth Pillai 4b071f2db7 update ipAddressHeaders 2026-04-29 19:54:21 +02:00
Amruth Pillai 80ca3a8875 update Dockerfile 2026-04-29 19:34:41 +02:00
Amruth Pillai e95be536fa remove CSP reporting 2026-04-29 19:19:36 +02:00
Amruth Pillai d6287dbd65 better rate limiting, verbose logging for username/slug path 2026-04-29 18:44:07 +02:00
Amruth Pillai 47abce351b sync translations with crowdin 2026-04-27 15:22:13 +02:00
Amruth Pillai 8f6c65b7fd chore(release): 🚀 v5.0.20 2026-04-27 15:21:07 +02:00
github-actions[bot]andCrowdin Bot 5a88ac12bf Sync Translations from Crowdin (#2935)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-27 15:13:05 +02:00
RuzenieAmruth Pillaiautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
118004b3d3 feat:icon colors (#2928)
Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-04-27 15:12:55 +02:00
github-actions[bot]andCrowdin Bot 6a8dd480cb Sync Translations from Crowdin (#2934)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-27 13:39:40 +02:00
Amruth Pillai 5d8126d4b0 feat: combine settings pages into a single integrations page 2026-04-27 12:56:15 +02:00
JamesGoslings 8566a9fd0f fix(i18n): translate Skills section title to Chinese (zh-CN) (#2931) 2026-04-27 10:47:46 +02:00
github-actions[bot]andCrowdin Bot 0d0bc61582 Sync Translations from Crowdin (#2932)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-27 10:47:22 +02:00
JamesGoslings e3af637100 docs: list Meowth alongside existing templates (#2929) 2026-04-27 10:47:14 +02:00
github-actions[bot]andCrowdin Bot f752145c57 Sync Translations from Crowdin (#2926)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-27 10:45:59 +02:00
Amruth Pillai b87f200767 feat: Add better email templates for password reset and email verification. 2026-04-27 10:45:44 +02:00
Amruth Pillai 73ec8b2ffb chore: release version 5.0.20 with new Meowth resume template and updated translations 2026-04-27 08:52:18 +02:00
github-actions[bot]andCrowdin Bot 107537999f Sync Translations from Crowdin (#2925)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-27 08:50:43 +02:00
Amruth Pillai e1bccbcc93 chore: update dependencies, cleanup exports (knip) 2026-04-27 08:48:35 +02:00
JamesGoslingsAmruth Pillaiautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
54e256be09 feat: add Meowth template with inline three-column entry header (Asian-style compact ATS) (#2923)
Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-04-27 08:45:08 +02:00
github-actions[bot]andCrowdin Bot b26d510294 Sync Translations from Crowdin (#2922)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-26 11:46:56 +02:00
Amruth Pillai 623ca5c675 allow loopback to localhost on mcp, only for local MCP clients 2026-04-26 10:59:10 +02:00
Amruth PillaiandClaude 76e00ae019 Revert "fix(resume): prevent orphaned section headings at page break (#2851)" (#2920)
This reverts commit 775f625f6e.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-26 01:23:22 +02:00
Amruth Pillai ff0ef12ecc Merge branch 'main' of github.com:amruthpillai/reactive-resume 2026-04-26 01:08:00 +02:00
Amruth Pillai 1bcb2e2af6 update changelog 2026-04-26 01:07:58 +02:00
github-actions[bot]andCrowdin Bot 796dc2ca41 Sync Translations from Crowdin (#2919)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-26 01:01:34 +02:00
github-actions[bot]andCrowdin Bot 80bf41254b Sync Translations from Crowdin (#2918)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-26 00:58:11 +02:00
Amruth Pillai bbc38d2f09 implement logic from #2853, thanks to @trigger-xyz 2026-04-26 00:57:50 +02:00
Christian PojoniClaude Opus 4.6autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
775f625f6e fix(resume): prevent orphaned section headings at page break (#2851)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-04-26 00:49:03 +02:00
2203933fac Sync Translations from Crowdin (#2917)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-04-26 00:48:24 +02:00
Platinum1154andAmruth Pillai 907e32a731 feat: add text color support to the rich text editor (#2903)
* feat: add text color support to the rich text editor

* improve design of text color picker

* Update translations for color picker features in multiple languages

---------

Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-04-26 00:48:03 +02:00
autofix-ci[bot] d6919e340b [autofix.ci] apply automated fixes 2026-04-25 22:34:53 +00:00
Amruth Pillai e05ae42fbb Remove "Reactive Resume" translations from multiple language files to streamline localization efforts. 2026-04-26 00:33:45 +02:00
github-actions[bot]andCrowdin Bot e99f39d139 Sync Translations from Crowdin (#2916)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-26 00:33:12 +02:00
Platinum1154andAmruth Pillai a4e7d6680d feat: add Chinese font options (#2905)
Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-04-26 00:32:42 +02:00
iago macedoandAmruth Pillai 77ad14b359 feat: add OpenRouter as AI provider (#2906)
Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-04-26 00:00:14 +02:00
Amruth Pillai 9b3916d43e chore: ⬆️ update dependencies 2026-04-25 23:34:19 +02:00
github-actions[bot]andCrowdin Bot 29f1aaf0da [skip ci] chore(i18n): sync translations from crowdin (#2914)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-25 17:32:04 +02:00
github-actions[bot]andCrowdin Bot 73cef02a4f Sync Translations from Crowdin (#2913)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-25 15:47:33 +02:00
github-actions[bot]andCrowdin Bot 2cb1897922 Sync Translations from Crowdin (#2912)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-25 15:32:52 +02:00
Amruth Pillai d0af9f4b4f test(security): cover url validation and form edge cases
Add and update tests for new security utilities and tightened UI behavior to prevent regressions in validation and error handling paths.

Made-with: Cursor
2026-04-25 15:31:19 +02:00
Amruth Pillai 08e9c80037 refactor(ui): improve error handling and input safety in app flows
Normalize frontend error rendering and tighten input/path handling across auth, builder, dashboard, and shared components for more resilient UX behavior.

Made-with: Cursor
2026-04-25 15:31:13 +02:00
Amruth Pillai a42dbcd452 feat(security): harden auth, oauth, and printer endpoints
Add stricter URL and redirect validation, endpoint rate limiting, safer defaults for printer and compose config, and CSP protections across server and API surfaces.

Made-with: Cursor
2026-04-25 15:31:06 +02:00
Amruth Pillai d3102565e4 chore(i18n): sync translation catalogs
Update locale catalogs to include the latest extracted strings used by the recent auth and security UX updates.

Made-with: Cursor
2026-04-25 15:30:51 +02:00
Amruth Pillai c0387298c5 docs(self-hosting): refresh docker and setup guidance
Clarify self-hosting, migration, and quickstart instructions to reflect the new secure defaults and deployment flow.

Made-with: Cursor
2026-04-25 15:30:47 +02:00
Amruth Pillai 9e1e593dc4 add SECURITY.md 2026-04-25 11:29:27 +02:00
Amruth Pillai 849aad6497 allow for running dev environment inside docker 2026-04-25 11:26:02 +02:00
Amruth Pillai 847d69b621 pin vite-plus versions to 0.1.19 2026-04-25 10:53:19 +02:00
Yeung Lihan 6ff754d125 fix: reduce preview wheel zoom sensitivity (#2911) 2026-04-25 09:43:58 +02:00
JamesGoslings ff3d4b1337 fix: align role period text to end in experience item (#2876) (#2908)
When an experience entry has multiple roles (Role Progression),
the period/date for each role was left-aligned in the grid layout,
causing it to appear off-center instead of right-aligned under the
location field.

Added `text-end` class to the role period element to match the
alignment behavior of the single-role header period. Uses `text-end`
instead of `text-right` for proper RTL language support.
2026-04-25 09:43:31 +02:00
github-actions[bot]andCrowdin Bot 2d2d5cd505 Sync Translations from Crowdin (#2902)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-23 14:17:30 +02:00
Amruth Pillai c6e8df0a00 - Pinned some packages to specific versions to avoid potential security vulnerabilities through transitive dependencies. (through running pnpm audit)
- Updated dependencies and lockfile.
- Synced translation catalogs from Crowdin.
2026-04-22 15:15:10 +02:00
Amruth Pillai 7df9b1e4b5 autocomplete passkey, if exists 2026-04-14 15:04:19 +02:00
github-actions[bot]andCrowdin Bot 0b4bac62a7 [skip ci] chore(i18n): sync translations from crowdin (#2892)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-14 14:42:06 +02:00
Amruth Pillai 82cb6e7590 update translations for passkeys 2026-04-14 14:40:07 +02:00
github-actions[bot]andCrowdin Bot 46dac6d3b1 [skip ci] chore(i18n): sync translations from crowdin (#2891)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-04-14 12:16:24 +02:00
Amruth Pillai b0b0d27c1f try again 2026-04-14 12:15:01 +02:00
Amruth Pillai b12d1184bc switch to crowdin github action 2026-04-14 11:53:20 +02:00
Amruth Pillai d6e0d9ac61 switch to crowdin github action 2026-04-14 11:50:07 +02:00
Amruth Pillai c19b9746c8 📦 v5.0.18 - https://docs.rxresu.me/changelog (Passkeys Support) 2026-04-14 10:51:04 +02:00
Amruth Pillai 4ed6177aee New translations en-us.po (Dutch) (#2886)
[ci skip]
2026-04-09 20:46:17 +02:00
Amruth Pillai 5900de101c update peer dependencies 2026-04-09 16:05:14 +02:00
Vedant Shankar BhavsarandAmruth Pillai 61b3324941 fix: improve email handling and user lookup in OAuth configuration (#2874)
* refactor: improve email handling and user lookup in OAuth configuration

* refactor: enhance OAuth user mapping and improve email handling

---------

Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-04-09 16:02:30 +02:00
Amruth Pillai 0e858c5967 update webfontlist.json 2026-04-09 15:15:08 +02:00
russandClaude 8c968e92f4 fix: correct Computer Modern Sans italic font file mappings (#2881)
The 400italic and 700italic variants for Computer Modern Sans pointed
to incorrect filenames. `cmunsl.woff` does not exist in the upstream
bitmaks/cm-web-fonts repository (returns 404 from jsDelivr CDN).

This causes PDF export to fail with "Waiting failed: 5000ms exceeded"
because Puppeteer's waitForFonts stalls on the 404, preventing the
page from signalling data-wf-loaded="true" within the timeout.

Correct mapping verified against the upstream @font-face declarations
in bitmaks/cm-web-fonts font/Sans/cmun-sans.css:

  - 400 normal:  cmunss.woff (unchanged)
  - 400 italic:  cmunsi.woff (was cmunsl.woff, which does not exist)
  - 700 normal:  cmunsx.woff (unchanged)
  - 700 italic:  cmunso.woff (was cmunsi.woff, which is the 400 italic)

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-09 15:12:30 +02:00
Amruth Pillai bea8ff1beb Fix MCP tool names for Claude Desktop incompatibility (#2885)
* fixes #2884, rename tool names for claude to work

* update dependencies
2026-04-09 15:03:18 +02:00
Amruth Pillai 85e0b0a96d further improvements to the mcp server 2026-04-09 10:06:50 +02:00
Amruth Pillai 1b266ba7ac Implement Resume Analysis (#2882)
* Implement Resume Analysis

* 📦 v5.0.17 - https://docs.rxresu.me/changelog
2026-04-09 09:04:27 +02:00
Amruth Pillai 1810dc8b07 better mcp server 2026-04-09 00:28:31 +02:00
Amruth Pillai 06b9da39ed Sync Translations from Crowdin (#2864)
* New translations en-us.po (Romanian)
[ci skip]

* New translations en-us.po (French)
[ci skip]

* New translations en-us.po (Spanish)
[ci skip]

* New translations en-us.po (Afrikaans)
[ci skip]

* New translations en-us.po (Arabic)
[ci skip]

* New translations en-us.po (Bulgarian)
[ci skip]

* New translations en-us.po (Catalan)
[ci skip]

* New translations en-us.po (Czech)
[ci skip]

* New translations en-us.po (Danish)
[ci skip]

* New translations en-us.po (German)
[ci skip]

* New translations en-us.po (Greek)
[ci skip]

* New translations en-us.po (Finnish)
[ci skip]

* New translations en-us.po (Hebrew)
[ci skip]

* New translations en-us.po (Hungarian)
[ci skip]

* New translations en-us.po (Italian)
[ci skip]

* New translations en-us.po (Japanese)
[ci skip]

* New translations en-us.po (Korean)
[ci skip]

* New translations en-us.po (Lithuanian)
[ci skip]

* New translations en-us.po (Dutch)
[ci skip]

* New translations en-us.po (Norwegian)
[ci skip]

* New translations en-us.po (Polish)
[ci skip]

* New translations en-us.po (Portuguese)
[ci skip]

* New translations en-us.po (Russian)
[ci skip]

* New translations en-us.po (Slovak)
[ci skip]

* New translations en-us.po (Slovenian)
[ci skip]

* New translations en-us.po (Albanian)
[ci skip]

* New translations en-us.po (Serbian (Cyrillic))
[ci skip]

* New translations en-us.po (Swedish)
[ci skip]

* New translations en-us.po (Turkish)
[ci skip]

* New translations en-us.po (Ukrainian)
[ci skip]

* New translations en-us.po (Chinese Simplified)
[ci skip]

* New translations en-us.po (Chinese Traditional)
[ci skip]

* New translations en-us.po (Vietnamese)
[ci skip]

* New translations en-us.po (Portuguese, Brazilian)
[ci skip]

* New translations en-us.po (Indonesian)
[ci skip]

* New translations en-us.po (Persian)
[ci skip]

* New translations en-us.po (Khmer)
[ci skip]

* New translations en-us.po (Tamil)
[ci skip]

* New translations en-us.po (Bengali)
[ci skip]

* New translations en-us.po (Marathi)
[ci skip]

* New translations en-us.po (Thai)
[ci skip]

* New translations en-us.po (Latvian)
[ci skip]

* New translations en-us.po (Azerbaijani)
[ci skip]

* New translations en-us.po (Hindi)
[ci skip]

* New translations en-us.po (Malay)
[ci skip]

* New translations en-us.po (Telugu)
[ci skip]

* New translations en-us.po (English, United Kingdom)
[ci skip]

* New translations en-us.po (Malayalam)
[ci skip]

* New translations en-us.po (Uzbek)
[ci skip]

* New translations en-us.po (Kannada)
[ci skip]

* New translations en-us.po (Odia)
[ci skip]

* New translations en-us.po (Amharic)
[ci skip]

* New translations en-us.po (Nepali)
[ci skip]

* New translations en-us.po (Swedish)
[ci skip]
2026-04-05 09:50:40 +02:00
Amruth Pillai 11373763fd fixes #2868 2026-04-05 09:03:49 +02:00
Amruth Pillai b3224ce59b Merge branch 'main' of github.com:amruthpillai/reactive-resume 2026-04-04 20:59:38 +02:00
Amruth Pillai 145b17de0f fix #2865, spacing between section items messed up 2026-04-04 20:59:30 +02:00
Amruth Pillai 623c5f6f81 Downgrade Cosign installer version to v3 2026-04-04 12:53:26 +02:00
Amruth Pillai bcbe70d231 📦 v5.0.16 - https://docs.rxresu.me/changelog 2026-04-04 12:31:24 +02:00
Amruth Pillai 8b52b9d8fc update translations 2026-04-04 12:29:10 +02:00
Amruth Pillai 4ecc66d081 Update title/metadata of generated PDF (#2863) 2026-04-04 12:28:32 +02:00
Amruth Pillai 10d58175f1 refactor: update layout of resume items for better alignment and spacing 2026-04-04 12:21:05 +02:00
Amruth Pillai 923f5f6173 fixes #2733: Bug where date range is displayed on separate line (#2862) 2026-04-04 12:03:09 +02:00
Amruth Pillai 9332e1e3ff chore: update GitHub Actions workflows to use Node 24 and upgrade action versions 2026-04-02 00:28:36 +02:00
AaronJoel Dev 77f31fa127 fix: prevent desktop horizontal overflow in home hero (#2854) 2026-04-02 00:16:16 +02:00
Amruth Pillai 4fd43657dc 📦 v5.0.15 - https://docs.rxresu.me/changelog 2026-04-02 00:14:54 +02:00
Aman Gupta d9a24448e8 fix: refactor useCSSVariables to ensure valid highest font weights (#2852) 2026-03-31 22:41:24 +02:00
Amruth Pillai 69ff78b656 Sync Translations from Crowdin (#2848)
* New translations en-us.po (Romanian)
[ci skip]

* New translations en-us.po (French)
[ci skip]

* New translations en-us.po (Spanish)
[ci skip]

* New translations en-us.po (Afrikaans)
[ci skip]

* New translations en-us.po (Arabic)
[ci skip]

* New translations en-us.po (Bulgarian)
[ci skip]

* New translations en-us.po (Catalan)
[ci skip]

* New translations en-us.po (Czech)
[ci skip]

* New translations en-us.po (Danish)
[ci skip]

* New translations en-us.po (German)
[ci skip]

* New translations en-us.po (Greek)
[ci skip]

* New translations en-us.po (Finnish)
[ci skip]

* New translations en-us.po (Hebrew)
[ci skip]

* New translations en-us.po (Hungarian)
[ci skip]

* New translations en-us.po (Italian)
[ci skip]

* New translations en-us.po (Japanese)
[ci skip]

* New translations en-us.po (Korean)
[ci skip]

* New translations en-us.po (Lithuanian)
[ci skip]

* New translations en-us.po (Dutch)
[ci skip]

* New translations en-us.po (Norwegian)
[ci skip]

* New translations en-us.po (Polish)
[ci skip]

* New translations en-us.po (Portuguese)
[ci skip]

* New translations en-us.po (Russian)
[ci skip]

* New translations en-us.po (Slovak)
[ci skip]

* New translations en-us.po (Slovenian)
[ci skip]

* New translations en-us.po (Albanian)
[ci skip]

* New translations en-us.po (Serbian (Cyrillic))
[ci skip]

* New translations en-us.po (Swedish)
[ci skip]

* New translations en-us.po (Turkish)
[ci skip]

* New translations en-us.po (Ukrainian)
[ci skip]

* New translations en-us.po (Chinese Simplified)
[ci skip]

* New translations en-us.po (Chinese Traditional)
[ci skip]

* New translations en-us.po (Vietnamese)
[ci skip]

* New translations en-us.po (Portuguese, Brazilian)
[ci skip]

* New translations en-us.po (Indonesian)
[ci skip]

* New translations en-us.po (Persian)
[ci skip]

* New translations en-us.po (Khmer)
[ci skip]

* New translations en-us.po (Tamil)
[ci skip]

* New translations en-us.po (Bengali)
[ci skip]

* New translations en-us.po (Marathi)
[ci skip]

* New translations en-us.po (Thai)
[ci skip]

* New translations en-us.po (Latvian)
[ci skip]

* New translations en-us.po (Azerbaijani)
[ci skip]

* New translations en-us.po (Hindi)
[ci skip]

* New translations en-us.po (Malay)
[ci skip]

* New translations en-us.po (Telugu)
[ci skip]

* New translations en-us.po (English, United Kingdom)
[ci skip]

* New translations en-us.po (Malayalam)
[ci skip]

* New translations en-us.po (Uzbek)
[ci skip]

* New translations en-us.po (Kannada)
[ci skip]

* New translations en-us.po (Odia)
[ci skip]

* New translations en-us.po (Amharic)
[ci skip]

* New translations en-us.po (Nepali)
[ci skip]
2026-03-29 23:34:21 +02:00
Amruth Pillai 0794b5c955 update dependencies 2026-03-29 23:09:25 +02:00
Amruth Pillai 5c986cc68d Sync Translations from Crowdin (#2838)
* New translations en-us.po (Romanian)
[ci skip]

* New translations en-us.po (French)
[ci skip]

* New translations en-us.po (Spanish)
[ci skip]

* New translations en-us.po (Afrikaans)
[ci skip]

* New translations en-us.po (Arabic)
[ci skip]

* New translations en-us.po (Bulgarian)
[ci skip]

* New translations en-us.po (Catalan)
[ci skip]

* New translations en-us.po (Czech)
[ci skip]

* New translations en-us.po (Danish)
[ci skip]

* New translations en-us.po (German)
[ci skip]

* New translations en-us.po (Greek)
[ci skip]

* New translations en-us.po (Finnish)
[ci skip]

* New translations en-us.po (Hebrew)
[ci skip]

* New translations en-us.po (Hungarian)
[ci skip]

* New translations en-us.po (Italian)
[ci skip]

* New translations en-us.po (Japanese)
[ci skip]

* New translations en-us.po (Korean)
[ci skip]

* New translations en-us.po (Lithuanian)
[ci skip]

* New translations en-us.po (Dutch)
[ci skip]

* New translations en-us.po (Norwegian)
[ci skip]

* New translations en-us.po (Polish)
[ci skip]

* New translations en-us.po (Portuguese)
[ci skip]

* New translations en-us.po (Russian)
[ci skip]

* New translations en-us.po (Slovak)
[ci skip]

* New translations en-us.po (Slovenian)
[ci skip]

* New translations en-us.po (Albanian)
[ci skip]

* New translations en-us.po (Serbian (Cyrillic))
[ci skip]

* New translations en-us.po (Swedish)
[ci skip]

* New translations en-us.po (Turkish)
[ci skip]

* New translations en-us.po (Ukrainian)
[ci skip]

* New translations en-us.po (Chinese Simplified)
[ci skip]

* New translations en-us.po (Chinese Traditional)
[ci skip]

* New translations en-us.po (Vietnamese)
[ci skip]

* New translations en-us.po (Portuguese, Brazilian)
[ci skip]

* New translations en-us.po (Indonesian)
[ci skip]

* New translations en-us.po (Persian)
[ci skip]

* New translations en-us.po (Khmer)
[ci skip]

* New translations en-us.po (Tamil)
[ci skip]

* New translations en-us.po (Bengali)
[ci skip]

* New translations en-us.po (Marathi)
[ci skip]

* New translations en-us.po (Thai)
[ci skip]

* New translations en-us.po (Latvian)
[ci skip]

* New translations en-us.po (Azerbaijani)
[ci skip]

* New translations en-us.po (Hindi)
[ci skip]

* New translations en-us.po (Malay)
[ci skip]

* New translations en-us.po (Telugu)
[ci skip]

* New translations en-us.po (English, United Kingdom)
[ci skip]

* New translations en-us.po (Malayalam)
[ci skip]

* New translations en-us.po (Uzbek)
[ci skip]

* New translations en-us.po (Kannada)
[ci skip]

* New translations en-us.po (Odia)
[ci skip]

* New translations en-us.po (Amharic)
[ci skip]

* New translations en-us.po (Nepali)
[ci skip]

* New translations en-us.po (Russian)
[ci skip]
2026-03-29 23:07:48 +02:00
autofix-ci[bot] 688c002822 [autofix.ci] apply automated fixes 2026-03-24 10:58:09 +00:00
Amruth Pillai ced49d5314 Update Crowdin configuration file 2026-03-24 11:57:03 +01:00
Amruth Pillai 3653baad9b 📦 v5.0.14 - https://docs.rxresu.me/changelog 2026-03-24 11:22:45 +01:00
b4aaf9712f feat(mcp): add OAuth 2.1 for claude.ai MCP connector (#2829)
* feat(mcp): add OAuth 2.1 authentication for claude.ai MCP connector

Enable OAuth 2.1 (RFC 8414 + RFC 7591) for the MCP endpoint using
better-auth's MCP plugin. This allows claude.ai and other MCP clients
to authenticate via Dynamic Client Registration and Authorization Code
flow with PKCE, using the existing login page.

- Add `mcp()` plugin to better-auth config with login page redirect
- Add `.well-known/oauth-authorization-server` discovery endpoint
- Add `.well-known/oauth-protected-resource` metadata endpoint
- Update MCP handler to accept Bearer tokens via `getMcpSession`
- Retain `x-api-key` fallback for backward compatibility
- Return proper HTTP 401 + WWW-Authenticate header for unauthed requests
- Add `oauthApplication`, `oauthAccessToken`, `oauthConsent` tables

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mcp): use typed AuthError and suppress noisy verifyApiKey throws

- Replace string-matching error detection with instanceof AuthError
- Wrap verifyApiKey in try-catch to avoid logging malformed key errors
- Move console.error below auth check so 401s don't pollute logs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mcp): add database migration for OAuth tables

Creates oauth_application, oauth_access_token, and oauth_consent tables
required for MCP OAuth 2.1 Dynamic Client Registration flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mcp): resolve OAuth Bearer token auth for oRPC tool calls

The oRPC context only checked session cookies and API keys, causing
MCP tool calls from OAuth clients (claude.ai) to fail with Unauthorized
even though the MCP endpoint itself authenticated successfully.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mcp): look up user by userId from OAuth access token

getMcpSession returns OAuthAccessToken (with userId), not a session
object with a user property. Must query the user table by userId.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor(mcp): migrate from deprecated mcp() plugin to @better-auth/oauth-provider

The better-auth MCP plugin is marked for deprecation in favor of the
OAuth Provider plugin. This refactors the entire OAuth 2.1 flow to use
@better-auth/oauth-provider with JWT-based token verification, replacing
the opaque token lookup via getMcpSession().

Key changes:
- Replace mcp() with jwt() + oauthProvider() in auth config
- Replace getMcpSession() with verifyAccessToken() (JWT/JWKS)
- Replace oauthApplication table with oauthClient (RFC 7591 compliant)
- Add oauthRefreshToken table and jwks table for JWT signing keys
- Extract shared authBaseUrl and verifyOAuthToken helper
- Hoist McpServer to module scope (avoid per-request reconstruction)
- Update .well-known discovery endpoints for OAuth Provider

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mcp): resolve OAuth 2.1 flow for claude.ai MCP connector

Multiple fixes required to make the full MCP OAuth flow work with
claude.ai's implementation:

- Add RFC 8414 discovery route at /.well-known/oauth-authorization-server/api/auth
  (claude.ai appends the issuer path per spec)
- Add /auth/oauth server route to handle login/consent flow
  (generates auth codes directly, bypassing h3 cookie issues)
- Default token_endpoint_auth_method to "none" via onRequest plugin hook
  (claude.ai omits this field, causing confidential client rejection)
- Strip prompt=consent from authorize requests via onRequest hook
  (better-auth checks prompt before skipConsent, causing redirect loops)
- Add validAudiences for MCP resource URL
  (JWT aud claim contains the MCP URL, not the base URL)
- Disable CSRF check for cross-origin OAuth flows
- Log token endpoint errors for debugging
- Set skipConsent on OAuth clients via /auth/oauth route

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mcp): harden OAuth security and enforce lock on delete

- Scope CSRF bypass to OAuth2 paths only instead of disabling globally
- Validate redirect_uri against registered client URIs (prevents code interception)
- Use pathname matching instead of fragile url.includes() for route guards
- Replace biased modulo code generation with crypto.randomBytes
- Enforce resume lock check on delete (previously silently ignored)
- Remove debug console.error logging of OAuth token response bodies
- Use Response.json() consistently for MCP 401 response

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update dependencies, refine ignore patterns, and enhance documentation

- Updated various dependencies in package.json and pnpm-lock.yaml for improved stability and features.
- Adjusted ignore patterns in knip.json to include specific component directories.
- Enhanced documentation for the MCP server, clarifying authentication methods and configuration options.
- Made minor adjustments to VSCode settings for better code organization.

* fix(mcp): resolve OAuth client registration and stale token handling

Claude.ai sends token_endpoint_auth_method: "client_secret_post" without
a client_secret during Dynamic Client Registration, causing Better Auth to
reject it as an unauthenticated confidential client. Force to "none" for
unauthenticated registrations.

Also catch JWKS verification errors (e.g. key rotation after redeployment)
so stale Bearer tokens return 401 instead of 200 with an error body,
allowing clients to re-initiate the OAuth flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* reiterate on tests

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-03-24 11:03:56 +01:00
Amruth Pillai e3274d7c95 New translations en-us.po (French) (#2834)
[ci skip]
2026-03-22 17:49:55 +01:00
Copilotamruthpillaicopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
a7a3d53dbd [WIP] Fix issue 2830 related to sidebar width slider (#2832)
* Initial plan

* fix: sidebar width slider not updating resume layout

Co-authored-by: amruthpillai <1134738+amruthpillai@users.noreply.github.com>
Agent-Logs-Url: https://github.com/amruthpillai/reactive-resume/sessions/55cb1943-2066-4871-8a12-0a0a4cb35fa6

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: amruthpillai <1134738+amruthpillai@users.noreply.github.com>
2026-03-21 08:24:42 +01:00
Amruth Pillai f8d776106f fixes #2826 2026-03-19 19:16:28 +01:00
Amruth Pillai e34f648455 remove input-otp component, upstream issues 2026-03-19 18:43:05 +01:00
Amruth Pillai f4e2d05f25 Merge branch 'main' of github.com:amruthpillai/reactive-resume 2026-03-19 12:55:46 +01:00
Amruth Pillai bbc17b8995 cleaner logging in dev and prod 2026-03-19 12:55:37 +01:00
Amruth Pillai a66bc13f4f Sync Translations from Crowdin (#2825)
* New translations en-us.po (Romanian)
[ci skip]

* New translations en-us.po (French)
[ci skip]

* New translations en-us.po (Spanish)
[ci skip]

* New translations en-us.po (Afrikaans)
[ci skip]

* New translations en-us.po (Arabic)
[ci skip]

* New translations en-us.po (Bulgarian)
[ci skip]

* New translations en-us.po (Catalan)
[ci skip]

* New translations en-us.po (Czech)
[ci skip]

* New translations en-us.po (Danish)
[ci skip]

* New translations en-us.po (German)
[ci skip]

* New translations en-us.po (Greek)
[ci skip]

* New translations en-us.po (Finnish)
[ci skip]

* New translations en-us.po (Hebrew)
[ci skip]

* New translations en-us.po (Hungarian)
[ci skip]

* New translations en-us.po (Italian)
[ci skip]

* New translations en-us.po (Japanese)
[ci skip]

* New translations en-us.po (Korean)
[ci skip]

* New translations en-us.po (Lithuanian)
[ci skip]

* New translations en-us.po (Dutch)
[ci skip]

* New translations en-us.po (Norwegian)
[ci skip]

* New translations en-us.po (Polish)
[ci skip]

* New translations en-us.po (Portuguese)
[ci skip]

* New translations en-us.po (Russian)
[ci skip]

* New translations en-us.po (Slovak)
[ci skip]

* New translations en-us.po (Slovenian)
[ci skip]

* New translations en-us.po (Albanian)
[ci skip]

* New translations en-us.po (Serbian (Cyrillic))
[ci skip]

* New translations en-us.po (Swedish)
[ci skip]

* New translations en-us.po (Turkish)
[ci skip]

* New translations en-us.po (Ukrainian)
[ci skip]

* New translations en-us.po (Chinese Simplified)
[ci skip]

* New translations en-us.po (Chinese Traditional)
[ci skip]

* New translations en-us.po (Vietnamese)
[ci skip]

* New translations en-us.po (Portuguese, Brazilian)
[ci skip]

* New translations en-us.po (Indonesian)
[ci skip]

* New translations en-us.po (Persian)
[ci skip]

* New translations en-us.po (Khmer)
[ci skip]

* New translations en-us.po (Tamil)
[ci skip]

* New translations en-us.po (Bengali)
[ci skip]

* New translations en-us.po (Marathi)
[ci skip]

* New translations en-us.po (Thai)
[ci skip]

* New translations en-us.po (Latvian)
[ci skip]

* New translations en-us.po (Azerbaijani)
[ci skip]

* New translations en-us.po (Hindi)
[ci skip]

* New translations en-us.po (Malay)
[ci skip]

* New translations en-us.po (Telugu)
[ci skip]

* New translations en-us.po (English, United Kingdom)
[ci skip]

* New translations en-us.po (Malayalam)
[ci skip]

* New translations en-us.po (Uzbek)
[ci skip]

* New translations en-us.po (Kannada)
[ci skip]

* New translations en-us.po (Odia)
[ci skip]

* New translations en-us.po (Amharic)
[ci skip]

* New translations en-us.po (Nepali)
[ci skip]
2026-03-19 10:23:34 +01:00
Amruth Pillai 7858efbd2b remove prepare script 2026-03-19 10:22:37 +01:00
Amruth Pillai 7da5e2c0c2 update schema.json and openapi/spec.json 2026-03-19 10:07:19 +01:00
Amruth Pillai 177c550a0c fix changelog formatting 2026-03-19 10:03:15 +01:00
1032 changed files with 150594 additions and 112074 deletions
-10
View File
@@ -1,10 +0,0 @@
FROM mcr.microsoft.com/devcontainers/typescript-node:24
RUN corepack enable
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
curl \
&& rm -rf /var/lib/apt/lists/*
EXPOSE 3000
-33
View File
@@ -1,33 +0,0 @@
{
"name": "Reactive Resume",
"service": "reactive_resume",
"dockerComposeFile": "docker-compose.yml",
"workspaceFolder": "/workspace",
"forwardPorts": [3000, 4000, 5432, 8333],
"portsAttributes": {
"3000": { "label": "Reactive Resume", "onAutoForward": "openBrowser" },
"4000": { "label": "Browserless (Printer)" },
"5432": { "label": "PostgreSQL" },
"8333": { "label": "SeaweedFS (S3)" }
},
"customizations": {
"vscode": {
"extensions": [
"oxc.oxc-vscode",
"bradlc.vscode-tailwindcss",
"lokalise.i18n-ally",
"typescriptteam.native-preview"
],
"settings": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.oxc": "always"
}
}
}
},
"postCreateCommand": "corepack enable && pnpm install"
}
-95
View File
@@ -1,95 +0,0 @@
services:
reactive_resume:
build:
context: ..
dockerfile: .devcontainer/Dockerfile
volumes:
- ..:/workspace:cached
command: sleep infinity
depends_on:
postgres:
condition: service_healthy
browserless:
condition: service_started
seaweedfs:
condition: service_healthy
seaweedfs_create_bucket:
condition: service_completed_successfully
environment:
TZ: Etc/UTC
APP_URL: http://localhost:3000
PRINTER_APP_URL: http://reactive_resume:3000
PRINTER_ENDPOINT: ws://browserless:3000?token=1234567890
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres
AUTH_SECRET: change-me-to-a-secure-secret-key-in-production
S3_ACCESS_KEY_ID: seaweedfs
S3_SECRET_ACCESS_KEY: seaweedfs
S3_REGION: us-east-1
S3_ENDPOINT: http://seaweedfs:8333
S3_BUCKET: reactive-resume
S3_FORCE_PATH_STYLE: "true"
postgres:
image: postgres:latest
restart: unless-stopped
environment:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- postgres_data:/var/lib/postgresql
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "postgres"]
start_period: 10s
interval: 30s
timeout: 10s
retries: 3
browserless:
image: ghcr.io/browserless/chromium:latest
restart: unless-stopped
environment:
QUEUED: "10"
HEALTH: "true"
CONCURRENT: "5"
TOKEN: "1234567890"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/pressure?token=1234567890"]
interval: 10s
timeout: 5s
retries: 10
seaweedfs:
image: chrislusf/seaweedfs:latest
restart: unless-stopped
command: server -s3 -filer -dir=/data -ip=0.0.0.0
environment:
AWS_ACCESS_KEY_ID: seaweedfs
AWS_SECRET_ACCESS_KEY: seaweedfs
volumes:
- seaweedfs_data:/data
healthcheck:
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://localhost:8888"]
start_period: 10s
interval: 30s
timeout: 10s
retries: 3
seaweedfs_create_bucket:
image: quay.io/minio/mc:latest
restart: on-failure
entrypoint: >
/bin/sh -c "
until mc alias set seaweedfs http://seaweedfs:8333 seaweedfs seaweedfs; do
echo 'Waiting for SeaweedFS...';
sleep 2;
done;
mc mb seaweedfs/reactive-resume --ignore-existing;
"
depends_on:
seaweedfs:
condition: service_healthy
volumes:
postgres_data:
seaweedfs_data:
+23 -7
View File
@@ -1,15 +1,31 @@
dist
docs
# VCS and editor state
.git
.gitignore
.cursor
.DS_Store
# Local configuration and runtime state
.env*
/data
# Dependency and package-manager caches
node_modules
**/node_modules
.pnpm-store
# Build, test, and framework output
dist
**/dist
.nitro
.cursor
.output
.vercel
.netlify
coverage
.DS_Store
.tanstack
node_modules
.turbo
**/.turbo
coverage
reports
# Generated service-worker assets are rebuilt during the web build.
public/sw.js
public/workbox-*.js
public/workbox-*.js
+38 -20
View File
@@ -1,18 +1,14 @@
# --- Server ---
TZ="Etc/UTC"
# --- Application ---
# Port used by the web server in local development and self-hosted containers.
PORT="3000"
# Public URL where the app is served. Used for auth callbacks, OAuth issuer URLs,
# OpenGraph metadata, and absolute upload URLs.
APP_URL="http://localhost:3000"
# Optional, uses APP_URL by default
# PLEASE READ: This should be set to an internal URL (like http://host.docker.internal:3000 or http://{docker_service}:3000)
# to let the browser navigate to a non-public instance of Reactive Resume.
# This is required when the printer service is running inside Docker, and cannot reach the app via the APP URL,
# which is usually when the APP_URL is localhost or a local network IP/hostname.
PRINTER_APP_URL="http://host.docker.internal:3000"
# --- Printer ---
PRINTER_ENDPOINT="ws://localhost:4000?token=1234567890"
# --- Database (PostgreSQL) ---
# PostgreSQL connection URL. In Docker Compose, the hostname is usually `postgres`;
# when running directly on your machine, `localhost` is typical.
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres"
# --- Authentication ---
@@ -20,25 +16,45 @@ DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres"
AUTH_SECRET="change-me-to-a-secure-secret-key-in-production"
# Better Auth Dashboard (optional)
# Enables the Better Auth Dashboard plugin when set, you probably don't need this.
BETTER_AUTH_API_KEY=""
# Social Auth (Google, optional)
# Set both values to enable Google sign-in.
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""
# Social Auth (GitHub, optional)
# Set both values to enable GitHub sign-in.
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""
# Social Auth (LinkedIn, optional)
# Set both values to enable LinkedIn sign-in.
LINKEDIN_CLIENT_ID=""
LINKEDIN_CLIENT_SECRET=""
# Custom OAuth Provider (optional)
# Set OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET plus either OAUTH_DISCOVERY_URL or
# the three manual endpoint URLs below.
OAUTH_PROVIDER_NAME=""
OAUTH_CLIENT_ID=""
OAUTH_CLIENT_SECRET=""
OAUTH_DISCOVERY_URL=""
OAUTH_AUTHORIZATION_URL=""
OAUTH_TOKEN_URL=""
OAUTH_USER_INFO_URL=""
# Space-separated scopes requested from the custom OAuth provider.
OAUTH_SCOPES="openid profile email"
# Comma-separated extra hosts/origins allowed for dynamic OAuth client redirect URIs.
# By default, only the APP_URL origin is allowed.
OAUTH_DYNAMIC_CLIENT_REDIRECT_HOSTS=""
# --- Email (optional) ---
# If all keys are disabled, the app logs the email to be sent to the console instead.
# If SMTP_HOST, SMTP_USER, SMTP_PASS, or SMTP_FROM is missing, the app logs the
# email to the console instead.
SMTP_HOST="localhost"
SMTP_PORT="1025"
SMTP_USER=""
@@ -59,14 +75,11 @@ S3_BUCKET="reactive-resume"
S3_FORCE_PATH_STYLE="true"
# --- Feature Flags ---
# This flag bypasses the check that the endpoint to fetch data for the printing of PDFs `getByIdForPrinter`, is only accessible from the server.
# Useful for when you want to debug the /printer/{resumeId} route to quickly take a peek at the page that is sent to the printer.
FLAG_DEBUG_PRINTER="false"
# This flag disables new signups, both on the web app and the server.
FLAG_DISABLE_SIGNUPS="false"
# This flag disables email/password login. Disables email verification, forgot password, and reset password flows. Users can still sign up via social auth (Google/GitHub/Custom OAuth), unless FLAG_DISABLE_SIGNUPS is also set to true.
# This flag disables email/password login. Disables email verification, forgot password, and reset password flows.
# Users can still sign up via social auth (Google/GitHub/Custom OAuth), unless FLAG_DISABLE_SIGNUPS is also set to true.
FLAG_DISABLE_EMAIL_AUTH="false"
# This flag disables the image processing.
@@ -75,6 +88,11 @@ FLAG_DISABLE_IMAGE_PROCESSING="false"
# --- Others ---
# Google Cloud API Key (optional)
# This is not used within Reactive Resume, but in src/scripts/fonts/generate.ts to generate a list of fonts served by Google Fonts.
# Note: Make sure "Google Fonts Developer API" is unrestricted.
# For font-list generation tooling.
# Requires "Google Fonts Developer API" to be enabled.
GOOGLE_CLOUD_API_KEY=""
# Crowdin (optional)
# For translation tooling.
CROWDIN_PROJECT_ID=""
CROWDIN_API_TOKEN=""
-1
View File
@@ -1 +0,0 @@
locales/*.po linguist-generated=true
+66 -66
View File
@@ -1,68 +1,68 @@
{
"$schema": "https://fundingjson.org/schema/v1.1.0.json",
"version": "v1.1.0",
"entity": {
"type": "individual",
"role": "maintainer",
"name": "Amruth Pillai",
"email": "im.amruth@gmail.com",
"description": "Software Engineer",
"webpageUrl": {
"url": "https://rxresu.me/funding.json"
}
},
"projects": [
{
"guid": "reactive-resume",
"name": "Reactive Resume",
"description": "A free and open-source resume builder that simplifies the process of creating, updating, and sharing your resume.",
"webpageUrl": {
"url": "https://rxresu.me"
},
"repositoryUrl": {
"url": "https://github.com/amruthpillai/reactive-resume",
"wellKnown": "https://github.com/amruthpillai/reactive-resume/blob/main/.github/.well-known/funding-manifest-urls"
},
"licenses": ["spdx:MIT"],
"tags": ["data", "design", "productivity", "resume-builder"]
}
],
"funding": {
"plans": [
{
"guid": "sponsor",
"status": "active",
"name": "Sponsor",
"description": "Support the project on a recurring basis by becoming a sponsor.",
"amount": 10,
"currency": "EUR",
"frequency": "monthly",
"channels": ["github", "open-collective"]
},
{
"guid": "donation",
"status": "active",
"name": "Donation",
"description": "Show your support for the project by making a one-time donation.",
"amount": 0,
"currency": "EUR",
"frequency": "one-time",
"channels": ["github", "open-collective"]
}
],
"channels": [
{
"guid": "github",
"type": "payment-provider",
"description": "GitHub Sponsors",
"address": "https://github.com/sponsors/AmruthPillai"
},
{
"guid": "open-collective",
"type": "payment-provider",
"description": "Open Collective",
"address": "https://opencollective.com/reactive-resume"
}
]
}
"$schema": "https://fundingjson.org/schema/v1.1.0.json",
"version": "v1.1.0",
"entity": {
"type": "individual",
"role": "maintainer",
"name": "Amruth Pillai",
"email": "hello@amruthpillai.com",
"description": "Software Engineer",
"webpageUrl": {
"url": "https://rxresu.me/funding.json"
}
},
"projects": [
{
"guid": "reactive-resume",
"name": "Reactive Resume",
"description": "A free and open-source resume builder that simplifies the process of creating, updating, and sharing your resume.",
"webpageUrl": {
"url": "https://rxresu.me"
},
"repositoryUrl": {
"url": "https://github.com/amruthpillai/reactive-resume",
"wellKnown": "https://github.com/amruthpillai/reactive-resume/blob/main/.github/.well-known/funding-manifest-urls"
},
"licenses": ["spdx:MIT"],
"tags": ["data", "design", "productivity", "resume-builder"]
}
],
"funding": {
"plans": [
{
"guid": "sponsor",
"status": "active",
"name": "Sponsor",
"description": "Support the project on a recurring basis by becoming a sponsor.",
"amount": 10,
"currency": "EUR",
"frequency": "monthly",
"channels": ["github", "open-collective"]
},
{
"guid": "donation",
"status": "active",
"name": "Donation",
"description": "Show your support for the project by making a one-time donation.",
"amount": 0,
"currency": "EUR",
"frequency": "one-time",
"channels": ["github", "open-collective"]
}
],
"channels": [
{
"guid": "github",
"type": "payment-provider",
"description": "GitHub Sponsors",
"address": "https://github.com/sponsors/AmruthPillai"
},
{
"guid": "open-collective",
"type": "payment-provider",
"description": "Open Collective",
"address": "https://opencollective.com/reactive-resume"
}
]
}
}
+21 -8
View File
@@ -8,21 +8,34 @@ on:
permissions:
contents: read
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
autofix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Checkout Repository
uses: actions/checkout@v6
- uses: voidzero-dev/setup-vp@v1
- name: Install pnpm
uses: pnpm/action-setup@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: "24"
cache: true
node-version: "lts/*"
cache: "pnpm"
- run: vp install
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- run: vp fmt
- run: vp lint --fix
- name: Remove Unused Dependencies
run: pnpm knip --fix
- uses: autofix-ci/action@7a166d7532b277f34e16238930461bf77f9d7ed8
- name: Lint and Format
run: pnpm check
- name: Autofix
uses: autofix-ci/action@7a166d7532b277f34e16238930461bf77f9d7ed8
+36
View File
@@ -0,0 +1,36 @@
name: Sync Translations from Crowdin
on:
push:
branches: ["main"]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
crowdin-sync:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout Repository
uses: actions/checkout@v6
- name: Sync Translations from Crowdin
uses: crowdin/github-action@v2
with:
download_translations: true
localization_branch_name: "l10n"
commit_message: "[skip ci] chore(i18n): sync translations from crowdin"
pull_request_title: "Sync Translations from Crowdin"
pull_request_body: "This is an automated pull request to sync translations from [Crowdin](https://crowdin.com/project/reactive-resume)."
pull_request_labels: "l10n"
pull_request_reviewers: "amruthpillai"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
+12 -11
View File
@@ -9,6 +9,7 @@ concurrency:
env:
IMAGE: ${{ github.repository }}
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
build:
@@ -41,16 +42,16 @@ jobs:
run: echo "version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -58,7 +59,7 @@ jobs:
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: |
ghcr.io/${{ env.IMAGE }}
@@ -68,7 +69,7 @@ jobs:
- name: Build and Push by Digest
id: build
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .
sbom: true
@@ -88,7 +89,7 @@ jobs:
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: digests-${{ matrix.arch }}
path: /tmp/digests/*
@@ -118,23 +119,23 @@ jobs:
run: echo "version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
- name: Download digests
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -152,7 +153,7 @@ jobs:
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: |
ghcr.io/${{ env.IMAGE }}
+48 -16
View File
@@ -1,19 +1,51 @@
dist
.env*
/data
.nitro
# Dependencies
node_modules
.pnpm-store
# Build Outputs
.output
.vercel
.cursor
TODO.md
coverage
.netlify
.DS_Store
.tanstack
node_modules
.wrangler
# Environment Variables
.env*
!.env.example
public/sw.js
public/sw.js.map
scripts/**/*.json
public/workbox-*.js
public/workbox-*.js.map
# IDEs and Editors
*~
*.swp
*.swo
.DS_Store
.idea
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# Log Files
logs
*.log*
# Turborepo
.turbo
# TanStack Start
.tanstack
# Testing
coverage
reports
# Cache
tmp
temp
.cache
# AI
.codex
.claude
.cursor
# Data
apps/web/data
+8 -10
View File
@@ -1,17 +1,15 @@
// @ts-check
const nextPackages = ["@monaco-editor/react"];
const betaPackages = ["drizzle-orm", "drizzle-kit", "drizzle-zod"];
/** @type {import('npm-check-updates').RunOptions} */
module.exports = {
upgrade: true,
install: "always",
packageManager: "pnpm",
target: (packageName) => {
if (nextPackages.includes(packageName)) return "@next";
if (betaPackages.includes(packageName)) return "@beta";
return "latest";
},
upgrade: true,
workspaces: true,
install: "always",
packageManager: "pnpm",
target: (packageName) => {
if (betaPackages.includes(packageName)) return "@beta";
return "latest";
},
};
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/utils/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158664889981519,"mode":420,"is_dir":false}},"order":["packages/utils/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"0c7a15dde9d26988","duration":955,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"hash":"18315d11067e0830","duration":9205,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"ee0217b2e9df145b45e6731ac512d88ad59406eee553ed1b197bdf1eef2d5689"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/env/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158665081126046,"mode":420,"is_dir":false}},"order":["packages/env/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"24552bdffdc5ebcb","duration":1146,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/fonts/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158665816497121,"mode":420,"is_dir":false}},"order":["packages/fonts/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"2c1f239ac1e9bd96","duration":1882,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/import/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158667091029787,"mode":420,"is_dir":false}},"order":["packages/import/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"5fff137e287b47d8","duration":3154,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"apps/web/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158668660018078,"mode":420,"is_dir":false}},"order":["apps/web/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"6711a052e760da9a","duration":3049,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/ui/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158666985313670,"mode":420,"is_dir":false}},"order":["packages/ui/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"72c3ccc9f2f5feed","duration":3048,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/scripts/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158665609656007,"mode":420,"is_dir":false}},"order":["packages/scripts/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"7ad6f44ecc30113b","duration":1673,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/schema/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158666036371217,"mode":420,"is_dir":false}},"order":["packages/schema/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"8ac845ee07e175fc","duration":2102,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/auth/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158667978449652,"mode":420,"is_dir":false}},"order":["packages/auth/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"a1fc5770a21706e7","duration":2896,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/email/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158665401936928,"mode":420,"is_dir":false}},"order":["packages/email/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"b5f38c54fffff57f","duration":1465,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/db/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158666974087786,"mode":420,"is_dir":false}},"order":["packages/db/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"b849023dfa3fccd9","duration":3037,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"hash":"baf3349509c6078b","duration":10422,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"d2396996b2d0bdfaf37211bb596304c9daba172ce6f30ef038c35f558dc27c1e"}
Binary file not shown.
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"hash":"c747964dd160f1ea","duration":12224,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"e19f2793896093dc74f2a4eb044a4b4d3eb636c2509fb38e823941865cdf28e3"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/ai/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158666319285663,"mode":420,"is_dir":false}},"order":["packages/ai/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"e1524476910e6054","duration":2383,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/api/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158668358064434,"mode":420,"is_dir":false}},"order":["packages/api/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"e956e719e41d711e","duration":2955,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"files":{"packages/pdf/.turbo/turbo-typecheck.log":{"size":29,"mtime_nanos":1778158667367331180,"mode":420,"is_dir":false}},"order":["packages/pdf/.turbo/turbo-typecheck.log"]}
+1
View File
@@ -0,0 +1 @@
{"hash":"fe9e2236067e95bd","duration":2476,"sha":"1b345014be41f65c6fe7ac9f42ddef9ef3a8575c","dirty_hash":"5c14d1e7f0f28737d20df1e16b72d63386130eec2a28a7842a26eab88a949a82"}
Binary file not shown.
+4
View File
@@ -0,0 +1,4 @@
{
"is_task_list_visible": true,
"active_task": null
}
+71
View File
@@ -0,0 +1,71 @@
#!/bin/sh
if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then
set -x
fi
if [ "$LEFTHOOK" = "0" ]; then
exit 0
fi
call_lefthook()
{
if test -n "$LEFTHOOK_BIN"
then
"$LEFTHOOK_BIN" "$@"
elif lefthook -h >/dev/null 2>&1
then
lefthook "$@"
elif /Users/amruth/Projects/reactive-resume/node_modules/.pnpm/lefthook-darwin-arm64@2.1.6/node_modules/lefthook-darwin-arm64/bin/lefthook -h >/dev/null 2>&1
then
/Users/amruth/Projects/reactive-resume/node_modules/.pnpm/lefthook-darwin-arm64@2.1.6/node_modules/lefthook-darwin-arm64/bin/lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"
elif go tool lefthook -h >/dev/null 2>&1
then
go tool lefthook "$@"
elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package lefthook >/dev/null 2>&1
then
swift package --build-path .build/lefthook --disable-sandbox lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif uv run lefthook -h >/dev/null 2>&1
then
uv run lefthook "$@"
elif mise exec -- lefthook -h >/dev/null 2>&1
then
mise exec -- lefthook "$@"
elif devbox run lefthook -h >/dev/null 2>&1
then
devbox run lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
fi
}
call_lefthook run "commit-msg" "$@"
+71
View File
@@ -0,0 +1,71 @@
#!/bin/sh
if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then
set -x
fi
if [ "$LEFTHOOK" = "0" ]; then
exit 0
fi
call_lefthook()
{
if test -n "$LEFTHOOK_BIN"
then
"$LEFTHOOK_BIN" "$@"
elif lefthook -h >/dev/null 2>&1
then
lefthook "$@"
elif /Users/amruth/Projects/reactive-resume/node_modules/.pnpm/lefthook-darwin-arm64@2.1.6/node_modules/lefthook-darwin-arm64/bin/lefthook -h >/dev/null 2>&1
then
/Users/amruth/Projects/reactive-resume/node_modules/.pnpm/lefthook-darwin-arm64@2.1.6/node_modules/lefthook-darwin-arm64/bin/lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"
elif go tool lefthook -h >/dev/null 2>&1
then
go tool lefthook "$@"
elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package lefthook >/dev/null 2>&1
then
swift package --build-path .build/lefthook --disable-sandbox lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif uv run lefthook -h >/dev/null 2>&1
then
uv run lefthook "$@"
elif mise exec -- lefthook -h >/dev/null 2>&1
then
mise exec -- lefthook "$@"
elif devbox run lefthook -h >/dev/null 2>&1
then
devbox run lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
fi
}
call_lefthook run "pre-commit" "$@"
-1
View File
@@ -1 +0,0 @@
vp staged
+1 -7
View File
@@ -1,9 +1,3 @@
{
"recommendations": [
"oxc.oxc-vscode",
"bradlc.vscode-tailwindcss",
"lokalise.i18n-ally",
"typescriptteam.native-preview",
"VoidZero.vite-plus-extension-pack"
]
"recommendations": ["biomejs.biome", "bradlc.vscode-tailwindcss", "typescriptteam.native-preview"]
}
+29 -40
View File
@@ -1,42 +1,31 @@
{
"[typescript]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"editor.codeActionsOnSave": {
"source.fixAll.oxc": "explicit"
},
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "file",
"files.associations": {
"*.css": "tailwindcss"
},
"files.readonlyInclude": {
"**/routeTree.gen.ts": true,
"pnpm-lock.yaml": true
},
"files.watcherExclude": {
"**/routeTree.gen.ts": true,
"locales/**.po": true,
"pnpm-lock.yaml": true
},
"i18n-ally.enabledParsers": ["po"],
"i18n-ally.localesPaths": ["locales"],
"i18n-ally.sourceLanguage": "en-US",
"oxc.enable.oxfmt": true,
"oxc.enable.oxlint": true,
"oxc.fmt.configPath": "./vite.config.ts",
"search.exclude": {
"**/routeTree.gen.ts": true,
"locales/**.po": true,
"pnpm-lock.yaml": true
},
"tailwindCSS.classFunctions": ["cn", "cva"],
"tailwindCSS.experimental.classRegex": [
["class:\\s*?[\"'`]([^\"'`]*).*?,"],
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["cn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
],
"tailwindCSS.experimental.configFile": "src/styles/globals.css",
"typescript.experimental.useTsgo": true
"biome.enabled": true,
"editor.codeActionsOnSave": {
"source.fixAll.biome": "explicit",
"source.organizeImports.biome": "explicit"
},
"editor.defaultFormatter": "biomejs.biome",
"files.readonlyInclude": {
"**/locales/**.po": true,
"**/routeTree.gen.ts": true,
"pnpm-lock.yaml": true
},
"files.watcherExclude": {
"**/locales/**.po": true,
"**/routeTree.gen.ts": true,
"pnpm-lock.yaml": true
},
"search.exclude": {
"**/locales/**.po": true,
"**/routeTree.gen.ts": true,
"pnpm-lock.yaml": true
},
"tailwindCSS.classFunctions": ["cn", "cva"],
"tailwindCSS.experimental.classRegex": [
["class:\\s*?[\"'`]([^\"'`]*).*?,"],
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["cn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
],
"tailwindCSS.experimental.configFile": "src/styles/globals.css",
"typescript.experimental.useTsgo": true
}
-126
View File
@@ -1,126 +0,0 @@
# AGENTS.md
## Cursor Cloud specific instructions
### Overview
Reactive Resume is a single-package full-stack TypeScript app (not a monorepo) built with TanStack Start (React 19, Vite, Nitro). It serves both frontend and API on port 3000.
### Infrastructure services
Before running the dev server, Docker must be running with at least PostgreSQL. Start services via `compose.dev.yml`:
```bash
sudo dockerd &>/var/log/dockerd.log &
sudo docker compose -f compose.dev.yml up -d postgres browserless
```
- **PostgreSQL** (port 5432) — required. The app auto-runs Drizzle migrations on startup via a Nitro plugin.
- **Browserless** (port 4000) — required for PDF export. Maps container port 3000 to host port 4000.
### Environment variables
Copy `.env.example` to `.env` if not present. Key notes for local dev:
- `APP_URL` — local dev server origin on port 3000.
- `PRINTER_APP_URL` — must use the Docker bridge gateway IP (not localhost) so the Browserless container can reach the app on the host. Get the IP with: `sudo docker network inspect reactive_resume_default --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'`
- `PRINTER_ENDPOINT` — websocket URL to Browserless on host port 4000 with token `1234567890`.
- `DATABASE_URL` — PostgreSQL connection using `postgres:postgres` credentials on localhost:5432.
- S3/Storage and SMTP vars can be left empty — the app falls back to local filesystem and console-logged emails.
### Common commands
See `scripts` in `package.json`. Key ones:
| Task | Command |
| -------------- | --------------------------------------------------------------- |
| Dev server | `pnpm dev` (port 3000) |
| Lint (Oxlint) | `pnpm lint` |
| Format (Oxfmt) | `pnpm fmt` |
| Typecheck | `pnpm typecheck` |
| DB migrations | `pnpm db:generate` / `pnpm db:migrate` (auto-runs on dev start) |
### Gotchas
- The Docker daemon needs `fuse-overlayfs` storage driver and `iptables-legacy` in the cloud VM (nested container environment).
- `pnpm.onlyBuiltDependencies` in `package.json` controls which packages are allowed to run install scripts — no interactive `pnpm approve-builds` needed.
- Email verification is optional in dev — after signup, click "Continue" to skip.
- Vite 8 is beta (`^8.0.0-beta.15`); Nitro uses a nightly build. Occasional upstream issues may occur.
<!--VITE PLUS START-->
# Using Vite+, the Unified Toolchain for the Web
This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. Vite+ is distinct from Vite, but it invokes Vite through `vp dev` and `vp build`.
## Vite+ Workflow
`vp` is a global binary that handles the full development lifecycle. Run `vp help` to print a list of commands and `vp <command> --help` for information about a specific command.
### Start
- create - Create a new project from a template
- migrate - Migrate an existing project to Vite+
- config - Configure hooks and agent integration
- staged - Run linters on staged files
- install (`i`) - Install dependencies
- env - Manage Node.js versions
### Develop
- dev - Run the development server
- check - Run format, lint, and TypeScript type checks
- lint - Lint code
- fmt - Format code
- test - Run tests
### Execute
- run - Run monorepo tasks
- exec - Execute a command from local `node_modules/.bin`
- dlx - Execute a package binary without installing it as a dependency
- cache - Manage the task cache
### Build
- build - Build for production
- pack - Build libraries
- preview - Preview production build
### Manage Dependencies
Vite+ automatically detects and wraps the underlying package manager such as pnpm, npm, or Yarn through the `packageManager` field in `package.json` or package manager-specific lockfiles.
- add - Add packages to dependencies
- remove (`rm`, `un`, `uninstall`) - Remove packages from dependencies
- update (`up`) - Update packages to latest versions
- dedupe - Deduplicate dependencies
- outdated - Check for outdated packages
- list (`ls`) - List installed packages
- why (`explain`) - Show why a package is installed
- info (`view`, `show`) - View package information from the registry
- link (`ln`) / unlink - Manage local package links
- pm - Forward a command to the package manager
### Maintain
- upgrade - Update `vp` itself to the latest version
These commands map to their corresponding tools. For example, `vp dev --port 3000` runs Vite's dev server and works the same as Vite. `vp test` runs JavaScript tests through the bundled Vitest. The version of all tools can be checked using `vp --version`. This is useful when researching documentation, features, and bugs.
## Common Pitfalls
- **Using the package manager directly:** Do not use pnpm, npm, or Yarn directly. Vite+ can handle all package manager operations.
- **Always use Vite commands to run tools:** Don't attempt to run `vp vitest` or `vp oxlint`. They do not exist. Use `vp test` and `vp lint` instead.
- **Running scripts:** Vite+ commands take precedence over `package.json` scripts. If there is a `test` script defined in `scripts` that conflicts with the built-in `vp test` command, run it using `vp run test`.
- **Do not install Vitest, Oxlint, Oxfmt, or tsdown directly:** Vite+ wraps these tools. They must not be installed directly. You cannot upgrade these tools by installing their latest versions. Always use Vite+ commands.
- **Use Vite+ wrappers for one-off binaries:** Use `vp dlx` instead of package-manager-specific `dlx`/`npx` commands.
- **Import JavaScript modules from `vite-plus`:** Instead of importing from `vite` or `vitest`, all modules should be imported from the project's `vite-plus` dependency. For example, `import { defineConfig } from 'vite-plus';` or `import { expect, test, vi } from 'vite-plus/test';`. You must not install `vitest` to import test utilities.
- **Type-Aware Linting:** There is no need to install `oxlint-tsgolint`, `vp lint --type-aware` works out of the box.
## Review Checklist for Agents
- [ ] Run `vp install` after pulling remote changes and before getting started.
- [ ] Run `vp check` and `vp test` to validate changes.
<!--VITE PLUS END-->
+45 -37
View File
@@ -1,39 +1,44 @@
# syntax=docker/dockerfile:1
# syntax=docker/dockerfile:1.7
# ---------- Dependencies Layer ----------
FROM node:24-slim AS dependencies
ARG NODE_VERSION=24
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
RUN mkdir -p /tmp/dev /tmp/prod
COPY package.json pnpm-lock.yaml /tmp/dev/
COPY package.json pnpm-lock.yaml /tmp/prod/
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
cd /tmp/dev && pnpm install --frozen-lockfile
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
cd /tmp/prod && pnpm install --frozen-lockfile --prod
# ---------- Builder Layer ----------
FROM node:24-slim AS builder
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
FROM node:${NODE_VERSION}-slim AS base
WORKDIR /app
COPY --from=dependencies /tmp/dev/node_modules ./node_modules
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
PNPM_HOME="/pnpm" \
PATH="/pnpm:$PATH" \
TURBO_TELEMETRY_DISABLED=1
RUN corepack enable
FROM base AS pruner
COPY . .
RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store,sharing=locked \
pnpm dlx turbo@2.9.9 prune web --docker
RUN pnpm run build
FROM base AS builder
COPY --from=pruner /app/out/json/ ./
COPY --from=pruner /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store,sharing=locked \
pnpm install --frozen-lockfile
# ---------- Runtime Layer ----------
FROM node:24-slim AS runtime
COPY --from=pruner /app/out/full/ ./
RUN pnpm turbo run build --filter=web
FROM base AS runtime-pruner
COPY . .
RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store,sharing=locked \
pnpm dlx turbo@2.9.9 prune @reactive-resume/runtime-externals --docker
FROM base AS runtime-deps
COPY --from=runtime-pruner /app/out/json/ ./
COPY --from=runtime-pruner /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store,sharing=locked \
pnpm --filter=@reactive-resume/runtime-externals deploy --prod --legacy /runtime-deps
FROM node:${NODE_VERSION}-slim AS runtime
LABEL maintainer="amruthpillai"
LABEL org.opencontainers.image.licenses="MIT"
@@ -44,20 +49,23 @@ LABEL org.opencontainers.image.url="https://rxresu.me"
LABEL org.opencontainers.image.documentation="https://docs.rxresu.me"
LABEL org.opencontainers.image.source="https://github.com/amruthpillai/reactive-resume"
RUN apt-get update && apt-get install -y --no-install-recommends curl \
&& rm -rf /var/lib/apt/lists/*
ENV NODE_ENV="production" \
PORT=3000
WORKDIR /app
ENV NODE_ENV=production
RUN mkdir -p /app/apps/web /app/data && chown node:node /app/data
COPY --from=builder /app/.output ./.output
COPY --from=builder /app/migrations ./migrations
COPY --from=dependencies /tmp/prod/node_modules ./node_modules
COPY --from=runtime-deps --chown=node:node /runtime-deps/node_modules ./node_modules
COPY --from=builder --chown=node:node /app/apps/web/.output ./apps/web/.output
COPY --from=pruner --chown=node:node /app/migrations ./migrations
WORKDIR /app/apps/web
USER node
EXPOSE 3000/tcp
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1
CMD ["node", "-e", "fetch('http://127.0.0.1:3000/api/health').then((r) => { if (!r.ok) process.exit(1); }).catch(() => process.exit(1));"]
ENTRYPOINT ["node", ".output/server/index.mjs"]
CMD ["node", ".output/server/index.mjs"]
+21 -16
View File
@@ -1,6 +1,6 @@
<div align="center">
<a href="https://rxresu.me">
<img src="public/opengraph/banner.jpg" alt="Reactive Resume" />
<img src="apps/web/public/opengraph/banner.jpg" alt="Reactive Resume" />
</a>
<h1>Reactive Resume</h1>
@@ -14,7 +14,7 @@
</p>
<p>
<img src="https://img.shields.io/github/package-json/v/amruthpillai/reactive-resume?style=flat-square" alt="Reactive Resume version">
<img src="https://img.shields.io/github/package-json/v/amruthpillai/reactive-resume?style=flat-square" alt="Reactive Resume Version">
<img src="https://img.shields.io/github/stars/amruthpillai/Reactive-Resume?style=flat-square" alt="GitHub Stars">
<img src="https://img.shields.io/github/license/amruthpillai/Reactive-Resume?style=flat-square" alt="License" />
<img src="https://img.shields.io/docker/pulls/amruthpillai/reactive-resume?style=flat-square" alt="Docker Pulls" />
@@ -69,63 +69,67 @@ Built with privacy as a core principle, Reactive Resume gives you complete owner
<table>
<tr>
<td align="center">
<img src="public/templates/jpg/azurill.jpg" alt="Azurill" width="150" />
<img src="apps/web/public/templates/jpg/azurill.jpg" alt="Azurill" width="150" />
<br /><sub><b>Azurill</b></sub>
</td>
<td align="center">
<img src="public/templates/jpg/bronzor.jpg" alt="Bronzor" width="150" />
<img src="apps/web/public/templates/jpg/bronzor.jpg" alt="Bronzor" width="150" />
<br /><sub><b>Bronzor</b></sub>
</td>
<td align="center">
<img src="public/templates/jpg/chikorita.jpg" alt="Chikorita" width="150" />
<img src="apps/web/public/templates/jpg/chikorita.jpg" alt="Chikorita" width="150" />
<br /><sub><b>Chikorita</b></sub>
</td>
<td align="center">
<img src="public/templates/jpg/ditto.jpg" alt="Ditto" width="150" />
<img src="apps/web/public/templates/jpg/ditto.jpg" alt="Ditto" width="150" />
<br /><sub><b>Ditto</b></sub>
</td>
</tr>
<tr>
<td align="center">
<img src="public/templates/jpg/gengar.jpg" alt="Gengar" width="150" />
<img src="apps/web/public/templates/jpg/gengar.jpg" alt="Gengar" width="150" />
<br /><sub><b>Gengar</b></sub>
</td>
<td align="center">
<img src="public/templates/jpg/glalie.jpg" alt="Glalie" width="150" />
<img src="apps/web/public/templates/jpg/glalie.jpg" alt="Glalie" width="150" />
<br /><sub><b>Glalie</b></sub>
</td>
<td align="center">
<img src="public/templates/jpg/kakuna.jpg" alt="Kakuna" width="150" />
<img src="apps/web/public/templates/jpg/kakuna.jpg" alt="Kakuna" width="150" />
<br /><sub><b>Kakuna</b></sub>
</td>
<td align="center">
<img src="public/templates/jpg/lapras.jpg" alt="Lapras" width="150" />
<img src="apps/web/public/templates/jpg/lapras.jpg" alt="Lapras" width="150" />
<br /><sub><b>Lapras</b></sub>
</td>
</tr>
<tr>
<td align="center">
<img src="public/templates/jpg/leafish.jpg" alt="Leafish" width="150" />
<img src="apps/web/public/templates/jpg/leafish.jpg" alt="Leafish" width="150" />
<br /><sub><b>Leafish</b></sub>
</td>
<td align="center">
<img src="public/templates/jpg/onyx.jpg" alt="Onyx" width="150" />
<img src="apps/web/public/templates/jpg/onyx.jpg" alt="Onyx" width="150" />
<br /><sub><b>Onyx</b></sub>
</td>
<td align="center">
<img src="public/templates/jpg/pikachu.jpg" alt="Pikachu" width="150" />
<img src="apps/web/public/templates/jpg/pikachu.jpg" alt="Pikachu" width="150" />
<br /><sub><b>Pikachu</b></sub>
</td>
<td align="center">
<img src="public/templates/jpg/rhyhorn.jpg" alt="Rhyhorn" width="150" />
<img src="apps/web/public/templates/jpg/rhyhorn.jpg" alt="Rhyhorn" width="150" />
<br /><sub><b>Rhyhorn</b></sub>
</td>
</tr>
<tr>
<td align="center">
<img src="public/templates/jpg/ditgar.jpg" alt="Ditgar" width="150" />
<img src="apps/web/public/templates/jpg/ditgar.jpg" alt="Ditgar" width="150" />
<br /><sub><b>Ditgar</b></sub>
</td>
<td align="center">
<img src="apps/web/public/templates/jpg/meowth.jpg" alt="Meowth" width="150" />
<br /><sub><b>Meowth</b></sub>
</td>
</tr>
</table>
@@ -180,9 +184,10 @@ Comprehensive guides are available at [docs.rxresu.me](https://docs.rxresu.me):
Reactive Resume can be self-hosted using Docker. The stack includes:
- **PostgreSQL** — Database for storing user data and resumes
- **Printer** — Headless Chromium service for PDF and screenshot generation
- **SeaweedFS** (optional) — S3-compatible storage for file uploads
> **From v5.1.0 onwards** — PDF generation now runs entirely client-side via `@react-pdf/renderer`. New deployments no longer require Browserless, Chromium, or any external print service as a dependency. The `PRINTER_*` and `BROWSERLESS_*` environment variables are no longer read and can be removed from your `.env`.
Pull the latest image from Docker Hub or GitHub Container Registry:
```bash
+34
View File
@@ -0,0 +1,34 @@
# Security Policy
## Supported Versions
Reactive Resume provides security updates for version `5.0.x` and newer.
Earlier major versions are no longer supported.
| Version | Supported |
| ------- | ------------------ |
| >= 5.0 | :white_check_mark: |
| 4.x | :x: |
| < 4.0 | :x: |
## Reporting a Vulnerability
If you believe you have found a security vulnerability, please report it
privately instead of opening a public issue.
Preferred reporting channels:
- Use GitHub's private vulnerability reporting for this repository.
- If that is unavailable, email `hello@amruthpillai.com` with the subject
`Security Vulnerability: Reactive Resume`.
Please include as much detail as possible, including:
- A description of the vulnerability and its impact.
- Steps to reproduce or a proof of concept.
- Affected versions, configuration, or deployment details.
- Any relevant logs, screenshots, or links.
You can expect an initial response within 7 days. If the report is accepted,
we will coordinate remediation and disclosure timing with you before publishing
details publicly.
File diff suppressed because one or more lines are too long
+2
View File
@@ -0,0 +1,2 @@
$ tsgo --noEmit
+25
View File
@@ -0,0 +1,25 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "base-nova",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "../../packages/ui/src/styles/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "phosphor",
"aliases": {
"components": "@reactive-resume/ui/components",
"utils": "@reactive-resume/utils/style",
"hooks": "@reactive-resume/ui/hooks",
"lib": "@reactive-resume/utils",
"ui": "@reactive-resume/ui/components"
},
"rtl": true,
"menuColor": "default-translucent",
"menuAccent": "subtle",
"registries": {}
}
+1
View File
@@ -0,0 +1 @@
2
+1
View File
@@ -0,0 +1 @@
36670
+1
View File
@@ -0,0 +1 @@
1
+77
View File
@@ -0,0 +1,77 @@
import { defineConfig } from "@lingui/cli";
import { formatter } from "@lingui/format-po";
export default defineConfig({
sourceLocale: "en-US",
pseudoLocale: "zu-ZA",
locales: [
"af-ZA",
"am-ET",
"ar-SA",
"az-AZ",
"bg-BG",
"bn-BD",
"ca-ES",
"cs-CZ",
"da-DK",
"de-DE",
"el-GR",
"en-US",
"en-GB",
"es-ES",
"fa-IR",
"fi-FI",
"fr-FR",
"he-IL",
"hi-IN",
"hu-HU",
"id-ID",
"it-IT",
"ja-JP",
"km-KH",
"kn-IN",
"ko-KR",
"lt-LT",
"lv-LV",
"ml-IN",
"mr-IN",
"ms-MY",
"ne-NP",
"nl-NL",
"no-NO",
"or-IN",
"pl-PL",
"pt-BR",
"pt-PT",
"ro-RO",
"ru-RU",
"sk-SK",
"sl-SI",
"sq-AL",
"sr-SP",
"sv-SE",
"ta-IN",
"te-IN",
"th-TH",
"tr-TR",
"uk-UA",
"uz-UZ",
"vi-VN",
"zh-CN",
"zh-TW",
"zu-ZA",
],
fallbackLocales: {
"zu-ZA": "en-US",
default: "en-US",
},
format: formatter({
lineNumbers: false,
}),
catalogs: [
{
path: "<rootDir>/locales/{locale}",
include: ["src"],
},
],
});
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More