Hey Codeforces,
Like many of you, I wanted an automated, hands-off way to back up all my Accepted solutions to GitHub so I could review my progress over time.
However, after trying existing extensions out there, I kept running into recurring issues:
Requiring an active Codeforces tab session: Many tools rely on content scripts scraping the DOM. If you practice using CLion/VS Code, close your tabs, or submit through tools like Competitive Companion, sync fails.
Hidden tabs popping up: Some tools spawn pinned/hidden tabs (
chrome.tabs.create), which break withACCESS_DENIED_ERRORon contest submissions.Overwriting solutions: Most tools key by Problem ID (e.g.
1872A.cpp). If you solve a problem with brute force and later rewrite an optimized $$$O(N \log N)$$$ version or port it to Rust, your earlier Accepted attempt gets overwritten.Plagiarism risk: Pushing solutions immediately to a public repository during live rated contests creates a real risk of plagiarism checks flagging your code.
To fix these issues, I built CommitForce from scratch. It is open-source (MIT licensed) and now officially available on both Microsoft Edge Add-ons and Mozilla Firefox AMO.

How it works under the hood
1. Zero Open Tabs Required (Cryptographic API Signing)
CommitForce does not touch the DOM or scrape HTML pages. Instead, it runs as a headless background service worker that queries the official Codeforces REST API (user.status with includeSources=true) using request signing:
apiSig = RAND + sha512Hex("RAND/user.status?PARAMS#SECRET")
RAND is 6 random hexadecimal characters. PARAMS is the query string with parameters sorted alphabetically by name (including apiKey and time). SECRET is your Codeforces API secret.
Because requests are cryptographically authenticated with your CF API credentials, Codeforces directly returns the full solution source code in the API payload. You can submit from any editor or IDE, close your browser, and synchronization occurs reliably in the background.
2. Contest-Safe Upload Protection
To stop the extension from publishing during a live contest: * CommitForce automatically checks whether a submission was made during an active contest. * If a contest is in progress, the solution is staged locally in an encrypted queue. * The solution is only synchronized to GitHub once the contest round has officially ended.
3. Preserves Every Accepted Solution (Deduplicated by Submission ID)
CommitForce organizes your repository by difficulty rating and problem folder, indexing files by Codeforces Submission ID:
Codeforces/
├── 800/
│ ├── 1872A_Two_Vessels/
│ │ ├── 222111000.cpp # First AC (C++ brute force)
│ │ └── 222111555.py # Second AC (Python rewrite)
│ └── 1915C_Can_I_Square/
│ └── 239840112.rs # Accepted solution (Rust)
└── 1200/
└── 1985E_Secret_Box/
└── 265001122.cpp
Git blob SHAs are computed locally before pushing to prevent duplicate commits or clobbering existing custom files.
4. Dynamic Streak Fire Engine & Dashboard
- Tracks your Current Streak, All-time Record, and rolling 365/30-day records computed from your full activity history.
- Features 6 reactive flame tiers (Cold Start → Kindling Ember → Steady Flame → Blazing Torch → Roaring Inferno → Legendary Plasma) directly in the extension popup and dashboard.
- Historical import lets you filter by problem rating, tags, or programming language.
5. Privacy
Your Codeforces API secret and GitHub tokens are encrypted on your device (PBKDF2-SHA256, 600,000 iterations, AES-GCM-256). The extension only asks for access to codeforces.com and api.github.com. The one server I run is a small Cloudflare Worker that handles the GitHub App sign-in token exchange. It never sees your Codeforces credentials or your code. No analytics. The source is MIT licensed, so you can audit it.
Limitations
- Chrome Web Store listing is still pending, so Chrome and Brave users need to manually load the release ZIP via
chrome://extensions. - You need to create a Codeforces API key and secret (Settings → API).
- Requests are limited to 1 per 2.1 seconds, so the first import of a large history takes a while.
- Automatic sync runs every 6 hours by default (configurable down to 1 hour). Use Sync now for an immediate run.
Links & Installation
- Microsoft Edge Add-ons (Approved & Live): Install on Edge (listed as "Codeforces → GitHub Sync" on Edge)
- Firefox Add-ons (Approved & Live): Install on Firefox AMO
- Chrome / Brave: Load unpacked release from GitHub Releases
- Source Code: GitHub: F0RREALTHO/codeforces-github-sync
If you find this useful or want to support future development, a ⭐ on GitHub would mean a lot!
Feel free to leave your thoughts, bug reports, or feature suggestions below. Happy coding!








Auto comment: topic has been updated by forrealtho (previous revision, new revision, compare).
What a great community to just hate on people..
hello sir how do you actually install this need a tutorial
You can download in directly on Firefox or windows edge browser, but if your are using brave or chrome then you have to download it from the releases from GitHub and load it into your browser extension
i have downloaded it i understood that i have to load it but how do i load it thats what i was asking this seemes pretty cool extension to have
i understood how to load it thanks for creating such a cool extension!
Thanks <3, consider reviewing it on the webstore or by star on github
It would be helpful if you could address the security aspect of this extension. I don't see any security.txt or anything related to security at all in the source code. Also, when entering the api key and the secret the extension just closes when you try to copy both of them. You can try reproducing this bug copy the key paste it and then try copying the secret the extension doesn't remember that you pasted a key and typed your cf handle earlier and hence you can't really copy and paste sequentially. Moreover, the ui is very AI, it would be lovely if you could make the ui cleaner. Also, I am sure I don't understand how this works but from what I understood is that GitHub sign-in needs a secret that can’t be kept inside an extension. So the extension sends the one-time GitHub login code, and later the refresh token, to the your Worker. The Worker swaps it for a GitHub token and passes it back. The repo’s version of that code (backend/src/index.ts) does only that and stores nothing. But I can’t check that the deployed Worker runs exactly this code, or that the store version of the extension matches the repo. It would be helpful if you could shed some light on this as well. Good job btw! Dunno the reason for downvotes lmao
thanks for checking it out!
good catch on the popup bug lol, completely forgot that popups lose state on blur because while testing i had my credentials in my clipboard...just pushed a fix to main that caches the draft in session storage so it wont reset when you switch tabs to copy the secret.
added a SECURITY.md in the repo explaining the encryption and permissions.
regarding the worker, you understood it correctly. it only does the github token swap so the client secret isnt exposed in extension code. it never touches your cf keys or solutions. but yeah fair point that you cant verify what's deployed, you can always self-host the worker from the backend folder if you want full control.
noted on the ui, will make it cleaner and more minimal in the next update.